#ifndef SignalHandler_INCLUDED
#define SignalHandler_INCLUDED

#include <vector>
#include <setjmp.h>
#include <signal.h>

/*
 * threads created by main() will inherit a copy of the signal mask.
*/
class SignalBlocker
{
    enum SignalBlockerType
    {
        SignalBlockerType_Thread,
        SignalBlockerType_Proc
    };
public:
    SignalBlocker(SignalBlockerType type = SignalBlockerType_Thread):m_type(type)
    {
        sigemptyset(&m_sset);
    }
    
    ~SignalBlocker()
    {
        if (m_type == SignalBlockerType_Thread)
        {
            pthread_sigmask(SIG_BLOCK, &m_oldSset, 0);
        }
        else if(m_type == SignalBlockerType_Proc)
        {
            sigprocmask(SIG_BLOCK, &m_oldSset,0);
        }
    }
    
    void block(unsigned int sig)        /// can call repeatedly
    {
        sigaddset(&m_sset, sig); 
        if (m_type == SignalBlockerType_Thread)
        {
            pthread_sigmask(SIG_BLOCK, &m_sset, &m_oldSset);
        }
        else if(m_type == SignalBlockerType_Proc)
        {
            sigprocmask(SIG_BLOCK, &m_sset, &m_oldSset);
        }
    }
private:
    sigset_t            m_sset;
    sigset_t            m_oldSset;
    SignalBlockerType   m_type;
};

typedef void (*Signal_Handler)(int sig);
typedef void (*Signal_Sigaction)(int sig, siginfo_t * siginfo, void * arg);

class SignalHandler
{
public:
    SignalHandler();

    ~SignalHandler();

    static void install(unsigned int sig,Signal_Handler callback);
    
    // flags: sigaction sa_flags
    static void install(unsigned int sig,unsigned int flags, Signal_Sigaction callback);
};

#endif
